| /* |
| * Copyright (c) 2012, 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.tools.core; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.Lists; |
| import com.google.dart.engine.AnalysisEngine; |
| import com.google.dart.engine.error.ErrorCode; |
| import com.google.dart.engine.index.Index; |
| import com.google.dart.engine.index.IndexFactory; |
| import com.google.dart.engine.index.IndexStore; |
| import com.google.dart.engine.sdk.DirectoryBasedDartSdk; |
| import com.google.dart.engine.utilities.instrumentation.Instrumentation; |
| import com.google.dart.engine.utilities.instrumentation.InstrumentationBuilder; |
| import com.google.dart.engine.utilities.logging.Logger; |
| import com.google.dart.server.generated.AnalysisServer; |
| import com.google.dart.server.generated.types.RequestError; |
| import com.google.dart.server.generated.types.ServerService; |
| import com.google.dart.server.internal.remote.DebugPrintStream; |
| import com.google.dart.server.internal.remote.FileReadMode; |
| import com.google.dart.server.internal.remote.RemoteAnalysisServerImpl; |
| import com.google.dart.server.internal.remote.StdioServerSocket; |
| import com.google.dart.server.utilities.logging.Logging; |
| import com.google.dart.tools.core.analysis.model.AnalysisServerData; |
| import com.google.dart.tools.core.analysis.model.ProjectManager; |
| import com.google.dart.tools.core.analysis.model.PubFolder; |
| import com.google.dart.tools.core.internal.MessageConsoleImpl; |
| import com.google.dart.tools.core.internal.OptionManager; |
| import com.google.dart.tools.core.internal.analysis.model.AnalysisServerDataImpl; |
| import com.google.dart.tools.core.internal.analysis.model.DartProjectManager; |
| import com.google.dart.tools.core.internal.analysis.model.ProjectManagerImpl; |
| import com.google.dart.tools.core.internal.analysis.model.WorkspaceAnalysisServerListener; |
| import com.google.dart.tools.core.internal.builder.AnalysisMarkerManager; |
| import com.google.dart.tools.core.internal.model.DartIgnoreManager; |
| import com.google.dart.tools.core.internal.model.DartProjectNature; |
| import com.google.dart.tools.core.internal.util.Extensions; |
| import com.google.dart.tools.core.internal.util.ResourceUtil; |
| import com.google.dart.tools.core.internal.util.Util; |
| import com.google.dart.tools.core.jobs.CleanLibrariesJob; |
| import com.google.dart.tools.core.model.DartIgnoreListener; |
| import com.google.dart.tools.core.model.DartSdkListener; |
| import com.google.dart.tools.core.model.DartSdkManager; |
| import com.google.dart.tools.core.pub.PubCacheManager_NEW; |
| import com.google.dart.tools.core.utilities.general.StringUtilities; |
| import com.google.dart.tools.core.utilities.io.FileUtilities; |
| import com.google.dart.tools.core.utilities.performance.PerformanceManager; |
| import com.google.dart.tools.core.utilities.yaml.PubYamlUtils; |
| |
| import org.apache.commons.lang3.ArrayUtils; |
| import org.apache.commons.lang3.StringUtils; |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceVisitor; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ProjectScope; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.ILog; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Plugin; |
| import org.eclipse.core.runtime.QualifiedName; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.content.IContentType; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.Version; |
| import org.osgi.service.prefs.BackingStoreException; |
| |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FileReader; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.PrintStream; |
| import java.io.PrintWriter; |
| import java.io.StringWriter; |
| import java.lang.management.ManagementFactory; |
| import java.text.SimpleDateFormat; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Hashtable; |
| import java.util.List; |
| import java.util.Properties; |
| |
| /** |
| * The class <code>DartCore</code> is used to access the elements modeling projects that have a Dart |
| * nature. |
| * |
| * @coverage dart.tools.core |
| */ |
| public class DartCore extends Plugin implements DartSdkListener { |
| |
| /** |
| * The unique instance of this class. |
| */ |
| private static DartCore PLUG_IN; |
| |
| /** |
| * The log used by {@link #logError(String)} and other local methods for logging errors, warnings, |
| * and information or <code>null</code> to use the default system log. |
| */ |
| private static ILog PLUGIN_LOG; |
| |
| /** |
| * Flag indicating whether instrumentation logging of errors is enabled |
| */ |
| private static boolean instrumentationLogErrorEnabled = true; |
| |
| /** |
| * The id of the plug-in that defines the Dart model. |
| */ |
| public static final String PLUGIN_ID = DartCore.class.getPackage().getName(); |
| |
| /** |
| * Name of file containing user-defined properties. |
| */ |
| public static final String EDITOR_PROPERTIES = "editor.properties"; |
| |
| /** |
| * The id of the project nature used for Dart projects. |
| */ |
| public static final String DART_PROJECT_NATURE = PLUGIN_ID + ".dartNature"; |
| |
| /** |
| * The id of the builder used for Dart projects. |
| */ |
| public static final String DART_BUILDER_ID = PLUGIN_ID + ".dartBuilder"; |
| |
| /** |
| * The id of the content type used to represent Dart compilation units. |
| */ |
| public static final String DART_SOURCE_CONTENT_TYPE = PLUGIN_ID + ".dartSourceFile"; |
| |
| /** |
| * Eclipse problem marker type used to display Dart compilation errors. |
| */ |
| public static final String DART_PROBLEM_MARKER_TYPE = PLUGIN_ID + ".problem"; |
| |
| /** |
| * Eclipse problem marker type used to display Dart hints. |
| */ |
| public static final String DART_HINT_MARKER_TYPE = PLUGIN_ID + ".hint"; |
| |
| /** |
| * Eclipse problem marker type used to display todo markers. |
| */ |
| public static final String DART_TASK_MARKER_TYPE = PLUGIN_ID + ".task"; |
| |
| /** |
| * Eclipse problem marker type used to Angular warning markers |
| */ |
| public static final String ANGULAR_WARNING_MARKER_TYPE = PLUGIN_ID + ".angular_warning"; |
| |
| /** |
| * Correction marker attribute. |
| */ |
| public static final String MARKER_ATTR_CORRECTION = "correction"; |
| |
| /** |
| * Extension for single unit compiled into JavaScript. |
| */ |
| public static final String EXTENSION_JS = "js"; |
| |
| /** |
| * Preference for the automatically running pub. |
| */ |
| public static final String PUB_AUTO_RUN_PREFERENCE = "pubAutoRun"; |
| |
| /** |
| * Preference for enabling hints. |
| */ |
| public static final String ENABLE_HINTS_PREFERENCE = "enableHints"; |
| |
| /** |
| * Preference for enabling lints. |
| */ |
| public static final String ENABLE_LINTS_PREFERENCE = "enableLints"; |
| |
| /** |
| * Preference for enabling dart2js related hints. |
| */ |
| public static final String ENABLE_HINTS_DART2JS_PREFERENCE = "enableHints_dart2js"; |
| |
| public static final String PROJECT_PREF_PACKAGE_ROOT = "projectPackageRoot"; |
| |
| /** |
| * Project package root for VM launches |
| */ |
| public static final String PROJECT_PREF_VM_PACKAGE_ROOT = "projectVmPackageRoot"; |
| |
| public static final String PREFS_DART2JS_FLAGS = "dart2jsFlags"; |
| |
| /** |
| * Preference for specifying location of the Dart SDK. |
| */ |
| public static final String PREFS_SDK_LOCATION = "sdkLocation"; |
| |
| /** |
| * Preference for specifying location of Dartium |
| */ |
| public static final String PREFS_DARTIUM_LOCATION = "dartiumLocation"; |
| |
| /** |
| * Preference to control if "not a member" warnings should be reported for inferred types. |
| */ |
| public static final String TYPE_CHECKS_FOR_INFERRED_TYPES = "typeChecksForInferredTypes"; |
| |
| public static final String PROJECT_PREF_DISABLE_DART_BASED_BUILDER = "disableDartBasedBuilder"; |
| |
| /** |
| * Preference for enabling usage collection |
| */ |
| public static final String PREFS_ENABLE_ANALYTICS = "enableAnalytics"; |
| |
| public static final String PREFS_SHOW_ANALYTICS_DIALOG = "showAnalyticsDialog"; |
| |
| // white listed dirs that can be used for pub build |
| public static final List<String> pubDirectories = Arrays.asList( |
| "assest", |
| "benchmark", |
| "bin", |
| "example", |
| "test", |
| "web"); |
| |
| /** |
| * Cached extensions for CSS files. |
| */ |
| private static final String[] CSS_FILE_EXTENSIONS = {"css"}; |
| |
| /** |
| * Cached extensions for HTML files. |
| */ |
| private static final String[] HTML_FILE_EXTENSIONS = {"html", "htm"}; |
| |
| /** |
| * Cached extensions for JS files. |
| */ |
| private static final String[] JS_FILE_EXTENSIONS = {"js"}; |
| |
| /** |
| * Cached extensions for TXT files. |
| */ |
| private static final String[] TXT_FILE_EXTENSIONS = {"txt"}; |
| |
| /** |
| * Cached extensions for files that are generated by the dartc compiler. |
| */ |
| private static final String[] DART_GENERATED_FILE_EXTENSIONS = {"api", "deps", "js", "map"}; |
| |
| /** |
| * Cached extensions for image files. |
| */ |
| public static final String[] IMAGE_FILE_EXTENSIONS = { |
| "bmp", "gif", "jpeg", "jpg", "png", "raw", "thm", "tif", "tiff"}; |
| |
| /** |
| * Name of directory for packages installed by pub |
| */ |
| public static final String PACKAGES_DIRECTORY_NAME = "packages"; |
| |
| /** |
| * Name of directory for build artifacts generated by pub |
| */ |
| public static final String BUILD_DIRECTORY_NAME = "build"; |
| |
| /** |
| * Name of "lib" directory in package |
| */ |
| public static final String LIB_DIRECTORY_NAME = "lib"; |
| |
| /** |
| * Path string for packages directory, uses "/" as path separator, equals "/packages/". |
| */ |
| public static final String PACKAGES_DIRECTORY_PATH = "/" + PACKAGES_DIRECTORY_NAME + "/"; |
| |
| /** |
| * Path string for packages directory in a url. |
| */ |
| public static final String PACKAGES_DIRECTORY_URL = "/" + PACKAGES_DIRECTORY_NAME + "/"; |
| |
| public static final String PACKAGE_SCHEME_SPEC = "package:"; |
| |
| /** |
| * Path string for lib directory in a url. |
| */ |
| public static final String LIB_URL_PATH = "/lib/"; |
| |
| /** |
| * Name of pubspec file |
| */ |
| public static final String PUBSPEC_FILE_NAME = "pubspec.yaml"; |
| |
| /** |
| * Name of special pubspec lock file |
| */ |
| public static final String PUBSPEC_LOCK_FILE_NAME = "pubspec.lock"; |
| |
| /** |
| * The name of the build.dart special file. |
| */ |
| public static final String BUILD_DART_FILE_NAME = "build.dart"; |
| |
| /** |
| * Used by the {@link DartDebugUserAgentManager} to indicate whether the allow remote connection |
| * dialog is open. |
| */ |
| public static boolean allowConnectionDialogOpen = false; |
| |
| /** |
| * The shared message console instance. |
| */ |
| private static final MessageConsole CONSOLE = new MessageConsoleImpl(); |
| |
| /** |
| * The QualifiedName for a resource remapping (a.foo ==> a.bar). |
| */ |
| private static final QualifiedName RESOURCE_REMAP_NAME = new QualifiedName( |
| PLUGIN_ID, |
| "resourceRemap"); |
| |
| /** |
| * The QualifiedName for the package version. |
| */ |
| public static final QualifiedName PUB_PACKAGE_VERSION = new QualifiedName( |
| DartCore.PLUGIN_ID, |
| "pub.package.version"); |
| |
| /** |
| * The QualifiedName for library names. |
| */ |
| public static final QualifiedName LIBRARY_NAME = new QualifiedName( |
| DartCore.PLUGIN_ID, |
| "libraryName"); |
| |
| /** |
| * The unique project manager used for analysis of anything in the workspace |
| */ |
| private static ProjectManager projectManager; |
| |
| /** |
| * Used to synchronize access to {@link #projectManager}. |
| */ |
| private static final Object projectManagerLock = new Object(); |
| |
| /** |
| * The unique {@link AnalysisServer} used for analysis of anything in the workspace. |
| */ |
| private static AnalysisServer analysisServer; |
| |
| /** |
| * The unique {@link AnalysisServerDataImpl} instance. |
| */ |
| private static AnalysisServerDataImpl analysisServerDataImpl = new AnalysisServerDataImpl(); |
| |
| /** |
| * The unique {@link WorkspaceAnalysisServerListener} instance. |
| */ |
| private static WorkspaceAnalysisServerListener analysisServerListener; |
| |
| /** |
| * Used to synchronize access to {@link #analysisServer}. |
| */ |
| private static final Object analysisServerLock = new Object(); |
| |
| /** |
| * Add the given listener for dart ignore changes to the Dart Model. Has no effect if an identical |
| * listener is already registered. |
| * |
| * @param listener the listener to add |
| */ |
| public static void addIgnoreListener(DartIgnoreListener listener) { |
| getIgnoreManager().addListener(listener); |
| } |
| |
| /** |
| * Add the given resource to the set of ignored resources. |
| * |
| * @param resource the resource to ignore |
| * @throws IOException if there was an error accessing the ignore file |
| * @throws CoreException if there was an error deleting markers |
| */ |
| public static void addToIgnores(IResource resource) throws IOException, CoreException { |
| getIgnoreManager().addToIgnores(resource); |
| } |
| |
| /** |
| * Remove any resource mapping for the given container. |
| * |
| * @param resource |
| */ |
| public static void clearResourceRemapping(IContainer container) { |
| try { |
| container.accept(new IResourceVisitor() { |
| @Override |
| public boolean visit(IResource resource) throws CoreException { |
| if (resource instanceof IFile) { |
| clearResourceRemapping((IFile) resource); |
| |
| return true; |
| } else if (resource instanceof IContainer) { |
| IContainer childContainer = (IContainer) resource; |
| |
| if (childContainer.getName().startsWith(".")) { |
| return false; |
| } else { |
| return true; |
| } |
| } else { |
| return false; |
| } |
| } |
| }); |
| } catch (CoreException e) { |
| DartCore.logError(e); |
| } |
| } |
| |
| /** |
| * Remove any resource mapping for the given file. |
| * |
| * @param resource |
| */ |
| public static void clearResourceRemapping(IFile resource) { |
| if (getResourceRemapping(resource) != null) { |
| setResourceRemapping(resource, null); |
| } |
| } |
| |
| /** |
| * Return true if directory contains a "packages" directory that is installed by pub |
| */ |
| public static boolean containsPackagesDirectory(File file) { |
| return new File(file, PACKAGES_DIRECTORY_NAME).isDirectory(); |
| } |
| |
| /** |
| * Return <code>true</code> if the directory contains a "pubspec.yaml" file |
| */ |
| public static boolean containsPubspecFile(File directory) { |
| return new File(directory, PUBSPEC_FILE_NAME).isFile(); |
| } |
| |
| /** |
| * Return an array of analysis server arguments |
| * |
| * @return a non-null array of arguments |
| */ |
| public static String[] getAdditionalAnalysisServerArguments() { |
| String value = getUserDefinedProperty(ANALYSIS_SERVER_ARG_PROP_KEY); |
| if (value == null) { |
| return StringUtilities.EMPTY_ARRAY; |
| } |
| return value.split(","); |
| } |
| |
| /** |
| * Answer the unique {@link AnalysisServer} used for analysis of anything in the workspace. |
| * |
| * @return the {@link AnalysisServer} (not {@code null}) |
| */ |
| public static AnalysisServer getAnalysisServer() { |
| synchronized (analysisServerLock) { |
| if (analysisServer == null) { |
| DartSdkManager sdkManager = DartSdkManager.getManager(); |
| if (!sdkManager.hasSdk()) { |
| DartCore.logError("Add the dart sdk (com.google.dart.sdk) as a JVM argument"); |
| System.exit(1); |
| } |
| |
| boolean isRunningFromSource = false; |
| String runtimePath = sdkManager.getSdk().getVmExecutable().getAbsolutePath(); |
| String analysisServerPath = DartCoreDebug.ANALYSIS_SERVER_PATH; |
| if (StringUtils.isEmpty(analysisServerPath)) { |
| String svnRoot = System.getProperty("com.google.dart.svnRoot"); |
| if (svnRoot == null) { |
| File analysisServerSnapshot = new File( |
| DartSdkManager.getManager().getSdk().getDirectory(), |
| "bin/snapshots/analysis_server.dart.snapshot"); |
| analysisServerPath = analysisServerSnapshot.getAbsolutePath(); |
| if (!analysisServerSnapshot.exists()) { |
| DartCore.logError("Analysis Server snapshot was not found in " |
| + analysisServerSnapshot.getAbsolutePath() + ", SDK is corrupt."); |
| System.exit(1); |
| } |
| } else { |
| analysisServerPath = svnRoot + "/pkg/analysis_server/bin/server.dart"; |
| isRunningFromSource = true; |
| } |
| } else { |
| isRunningFromSource = true; |
| } |
| |
| String packageRoot = System.getProperty("com.google.dart.packageRoot"); |
| if (packageRoot == null && isRunningFromSource) { |
| DartCore.logError("To run analysis server from source, a package root must be " |
| + "supplied using -Dcom.google.dart.packageRoot."); |
| System.exit(1); |
| } |
| |
| try { |
| String[] additionalArguments = DartCore.getAdditionalAnalysisServerArguments(); |
| // prepare debug stream |
| DebugPrintStream debugStream; |
| { |
| String logPath = DartCoreDebug.ANALYSIS_SERVER_LOG_FILE; |
| if (StringUtils.isBlank(logPath)) { |
| debugStream = null; |
| } else if ("console".equals(logPath)) { |
| debugStream = new DebugPrintStream() { |
| @Override |
| public void println(String s) { |
| if (s.length() > 1000) { |
| s = s.substring(0, 1000) + "..."; |
| } |
| System.out.println(s); |
| } |
| }; |
| } else { |
| @SuppressWarnings("resource") |
| final PrintStream fileStream = new PrintStream(logPath); |
| debugStream = new DebugPrintStream() { |
| @Override |
| public void println(String s) { |
| fileStream.println(s); |
| } |
| }; |
| } |
| } |
| // additional options |
| if (DartCoreDebug.ANALYSIS_SERVER_INCREMENTAL_RESOLUTION_API) { |
| additionalArguments = ArrayUtils.add( |
| additionalArguments, |
| "--enable-incremental-resolution-api"); |
| } |
| if (DartCoreDebug.ANALYSIS_SERVER_NEW_TASK_MODEL) { |
| additionalArguments = ArrayUtils.add(additionalArguments, "--enable-new-task-model"); |
| } |
| { |
| String log = DartCoreDebug.ANALYSIS_SERVER_INCREMENTAL_RESOLUTION_LOG; |
| if (!StringUtils.isEmpty(log)) { |
| additionalArguments = ArrayUtils.add( |
| additionalArguments, |
| "--incremental-resolution-log=" + log); |
| } |
| } |
| if (DartCoreDebug.ANALYSIS_SERVER_INCREMENTAL_RESOLUTION_VALIDATION) { |
| additionalArguments = ArrayUtils.add( |
| additionalArguments, |
| "--incremental-resolution-validation"); |
| } |
| { |
| String log = DartCoreDebug.ANALYSIS_SERVER_INSTRUMENTATION_LOG_FILE; |
| if (!StringUtils.isEmpty(log)) { |
| log = log.trim(); |
| if (log.length() > 0) { |
| additionalArguments = ArrayUtils.add( |
| additionalArguments, |
| "--instrumentation-log-file=" + log); |
| } |
| } |
| } |
| if (DartCoreDebug.ANALYSIS_SERVER_PRINT_TO_CONSOLE) { |
| additionalArguments = ArrayUtils.add(additionalArguments, "--internal-print-to-console"); |
| } |
| // HTTP port |
| int httpPort = 0; |
| if (DartCoreDebug.ANALYSIS_SERVER_HTTP_PORT != null |
| && !DartCoreDebug.ANALYSIS_SERVER_HTTP_PORT.isEmpty()) { |
| try { |
| httpPort = Integer.parseInt(DartCoreDebug.ANALYSIS_SERVER_HTTP_PORT); |
| } catch (NumberFormatException e) { |
| DartCore.logError("Analysis server HTTP port must be an integer."); |
| System.exit(1); |
| } |
| } |
| // create server, if "com.google.dart.svnRoot" flag was not set then use snapshot |
| StdioServerSocket socket = new StdioServerSocket( |
| runtimePath, |
| analysisServerPath, |
| packageRoot, |
| debugStream, |
| additionalArguments, |
| DartCoreDebug.ANALYSIS_SERVER_DEBUG, |
| DartCoreDebug.ANALYSIS_SERVER_PROFILE, |
| httpPort, |
| false, |
| FileReadMode.AS_IS); |
| if (isPluginsBuild()) { |
| // plugin mode |
| socket.setClientId("org.dartlang.dartplugin"); |
| } else { |
| // editor mode |
| socket.setClientId("org.dartlang.darteditor"); |
| } |
| socket.setClientVersion(getVersion()); |
| // start server |
| analysisServer = new RemoteAnalysisServerImpl(socket); |
| analysisServerDataImpl.setServer(analysisServer); |
| analysisServerListener = new WorkspaceAnalysisServerListener( |
| analysisServerDataImpl, |
| new DartProjectManager( |
| ResourcesPlugin.getWorkspace().getRoot(), |
| analysisServer, |
| DartIgnoreManager.getInstance())); |
| analysisServer.addAnalysisServerListener(analysisServerListener); |
| analysisServer.start(); |
| analysisServer.server_setSubscriptions(ImmutableList.of(ServerService.STATUS)); |
| analysisServerDataImpl.updateOptions(); |
| } catch (Throwable e) { |
| DartCore.logError("Enable to start stdio server", e); |
| System.exit(1); |
| } |
| } |
| } |
| return analysisServer; |
| } |
| |
| /** |
| * Answer the unique {@link AnalysisServerData} used to provide analysis information in the |
| * workspace. |
| * |
| * @return the {@link AnalysisServerData} (not {@code null}) |
| */ |
| public static AnalysisServerData getAnalysisServerData() { |
| getAnalysisServer(); |
| return analysisServerDataImpl; |
| } |
| |
| /** |
| * Answer the application directory (a directory contains a "packages" directory and a |
| * "pubspec.yaml" file) directly or indirectly containing the specified file or the file itself if |
| * it is an application directory. |
| * |
| * @param libFileOrDir the library file or directory |
| * @return the context in which the specified library should be analyzed (not <code>null</code>) |
| */ |
| public static File getApplicationDirectory(File file) { |
| while (file != null) { |
| if (isApplicationDirectory(file)) { |
| return file; |
| } |
| file = file.getParentFile(); |
| } |
| return null; |
| } |
| |
| /** |
| * Answer the application directory (a directory that contains a "packages" directory and a |
| * "pubspec.yaml" file) directly or indirectly containing the specified resource or the resource |
| * itself if it is an application directory. |
| * |
| * @param resource the file or directory |
| * @return the directory with the pubspec for the given file |
| */ |
| public static IContainer getApplicationDirectory(IResource resource) { |
| IContainer container; |
| if (resource instanceof IFile) { |
| container = resource.getParent(); |
| } else { |
| container = (IContainer) resource; |
| } |
| while (container != null) { |
| if (isApplicationDirectory(container)) { |
| return container; |
| } |
| container = container.getParent(); |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the day (yyyy-MM-dd) the product was built. |
| */ |
| public static String getBuildDate() { |
| return "@BUILDDATE@"; |
| } |
| |
| /** |
| * Returns the SVN revision number as a String. |
| */ |
| public static String getBuildId() { |
| return "@REVISION@"; |
| } |
| |
| /** |
| * Return a unique token that can be used to determine whether cached data that changes only when |
| * the version of the editor changes is still valid. |
| * |
| * @return a token used to determine the validity of cached data |
| */ |
| public static String getBuildIdOrDate() { |
| String buildIdOrDate = getBuildId(); |
| if (buildIdOrDate.startsWith("@")) { |
| buildIdOrDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); |
| } |
| return buildIdOrDate; |
| } |
| |
| /** |
| * Returns the shared message console. Unlike the log ({@link DartCore#getLog()}), the console is |
| * intended for communication with the end-user. |
| * |
| * @return the message console |
| */ |
| public static MessageConsole getConsole() { |
| return CONSOLE; |
| } |
| |
| /** |
| * Return the list of known Dart-like file extensions. Dart-like extensions are defined in the |
| * {@link Platform.getContentManager() content type manager} for the |
| * {@link #DART_SOURCE_CONTENT_TYPE}. Note that a Dart-like extension does not include the leading |
| * dot, and that the "dart" extension is always defined as a Dart-like extension. |
| * |
| * @return the list of known Dart-like file extensions |
| */ |
| public static String[] getDartLikeExtensions() { |
| IContentType dartContentType = Platform.getContentTypeManager().getContentType( |
| DART_SOURCE_CONTENT_TYPE); |
| HashSet<String> extensionSet = new HashSet<String>(); |
| for (IContentType contentType : Platform.getContentTypeManager().getAllContentTypes()) { |
| if (contentType.isKindOf(dartContentType)) { |
| for (String extension : contentType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC)) { |
| extensionSet.add(extension); |
| } |
| } |
| } |
| extensionSet.remove(Extensions.DART); |
| ArrayList<String> extensionList = new ArrayList<String>(extensionSet); |
| extensionList.add(0, Extensions.DART); |
| return extensionList.toArray(new String[extensionList.size()]); |
| } |
| |
| /** |
| * Returns all existing and open workspace Dart projects. |
| */ |
| public static IProject[] getDartProjects() { |
| List<IProject> dartProjects = Lists.newArrayList(); |
| IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); |
| for (IProject project : projects) { |
| if (!project.isAccessible()) { |
| continue; |
| } |
| if (!DartProjectNature.hasDartNature(project)) { |
| continue; |
| } |
| if (PubCacheManager_NEW.isPubCacheProject(project)) { |
| continue; |
| } |
| dartProjects.add(project); |
| } |
| return dartProjects.toArray(new IProject[dartProjects.size()]); |
| } |
| |
| /** |
| * Return a table of all known configurable options with their default values. These options allow |
| * to configure the behavior of the underlying components. The client may safely use the result as |
| * a template that they can modify and then pass to {@link #setOptions()}</code>. |
| * <p> |
| * Helper constants have been defined on DartPreferenceConstants for each of the option IDs |
| * (categorized in Code assist option ID, Compiler option ID and Core option ID) and some of their |
| * acceptable values (categorized in Option value). Some options accept open value sets beyond the |
| * documented constant values. |
| * <p> |
| * Note: each release may add new options. |
| * |
| * @return a table of all known configurable options with their default values |
| */ |
| public static Hashtable<String, String> getDefaultOptions() { |
| return null; |
| } |
| |
| public static File getEclipseInstallationDirectory() { |
| return new File(Platform.getInstallLocation().getURL().getFile()); |
| } |
| |
| /** |
| * Return the workspace root default charset encoding. |
| * |
| * @return the name of the default charset encoding for the workspace root |
| */ |
| public static String getEncoding() { |
| try { |
| return ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset(); |
| } catch (IllegalStateException exception) { |
| // happen when there's no workspace (see bug |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=216817) |
| // or when it is shutting down (see bug |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=60687) |
| return System.getProperty("file.encoding"); //$NON-NLS-1$ |
| } catch (CoreException exception) { |
| // fails silently and return plugin global encoding if core exception |
| // occurs |
| } |
| return ResourcesPlugin.getEncoding(); |
| } |
| |
| /** |
| * Extract {@link ErrorCode} form the given {@link IMarker}. |
| * |
| * @return the {@link ErrorCode}, may be {@code null}. |
| */ |
| public static ErrorCode getErrorCode(IMarker marker) { |
| return AnalysisMarkerManager.getErrorCode(marker); |
| } |
| |
| /** |
| * Return the DartIgnoreManager |
| */ |
| public static DartIgnoreManager getIgnoreManager() { |
| if (DartCoreDebug.ENABLE_ANALYSIS_SERVER) { |
| return DartIgnoreManager.getInstance(); |
| } else { |
| return getProjectManager().getIgnoreManager(); |
| } |
| } |
| |
| /** |
| * Utility method for returning one option value only. Equivalent to |
| * <code>DartCore.getOptions().get(optionName)</code> Note that it may answer <code>null</code> if |
| * this option does not exist. |
| * <p> |
| * Helper constants have been defined on DartPreferenceConstants for each of the option IDs |
| * (categorized in Code assist option ID, Compiler option ID and Core option ID) and some of their |
| * acceptable values (categorized in Option value). Some options accept open value sets beyond the |
| * documented constant values. |
| * <p> |
| * Note: each release may add new options. |
| * |
| * @param optionName the name of the option whose value is to be returned |
| * @return the value of a given option |
| */ |
| public static String getOption(String optionName) { |
| return OptionManager.getInstance().getOption(optionName); |
| } |
| |
| /** |
| * Return the table of the current options. Initially, all options have their default values, and |
| * this method returns a table that includes all known options. |
| * <p> |
| * Helper constants have been defined on DartPreferenceConstants for each of the option IDs |
| * (categorized in Code assist option ID, Compiler option ID and Core option ID) and some of their |
| * acceptable values (categorized in Option value). Some options accept open value sets beyond the |
| * documented constant values. |
| * <p> |
| * Note: each release may add new options. |
| * <p> |
| * Returns a default set of options even if the platform is not running. |
| * </p> |
| * |
| * @return table of current settings of all options (key type: <code>String</code>; value type: |
| * <code>String</code>) |
| */ |
| public static HashMap<String, String> getOptions() { |
| return OptionManager.getInstance().getOptions(); |
| } |
| |
| /** |
| * Return the unique instance of this class. |
| * |
| * @return the unique instance of this class |
| */ |
| public static DartCore getPlugin() { |
| return PLUG_IN; |
| } |
| |
| /** |
| * Answer the unique project manager used for analysis of anything in the workspace. |
| * |
| * @return the manager (not {@code null}) |
| */ |
| public static ProjectManager getProjectManager() { |
| synchronized (projectManagerLock) { |
| if (projectManager == null) { |
| // start index |
| final Index index; |
| { |
| File stateDir = getPlugin().getStateLocation().toFile(); |
| File indexDir = new File(stateDir, "index"); |
| indexDir.mkdirs(); |
| IndexStore indexStore = IndexFactory.newFileIndexStore(indexDir); |
| index = IndexFactory.newIndex(indexStore); |
| Thread thread = new Thread() { |
| @Override |
| public void run() { |
| index.run(); |
| } |
| }; |
| thread.setName("Index Thread"); |
| thread.setDaemon(true); |
| thread.start(); |
| } |
| // create ProjectManagerImpl |
| projectManager = new ProjectManagerImpl( |
| ResourcesPlugin.getWorkspace().getRoot(), |
| DartSdkManager.getManager().getSdk(), |
| DartSdkManager.getManager().getSdkContextId(), |
| index, |
| DartIgnoreManager.getInstance()); |
| } |
| } |
| return projectManager; |
| } |
| |
| /** |
| * @return the mapping for the given resource, if any |
| */ |
| public static String getResourceRemapping(IFile originalResource) { |
| try { |
| return originalResource.getPersistentProperty(RESOURCE_REMAP_NAME); |
| } catch (CoreException e) { |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the name of the directory in packages that is linked to the "lib" folder in the project |
| * |
| * @param project |
| * @return the name of the directory, <code>null</code> if there is no self linked packages folder |
| */ |
| public static String getSelfLinkedPackageName(IResource resource) { |
| String packageName = null; |
| |
| try { |
| IContainer appFolder = getApplicationDirectory(resource); |
| |
| if (appFolder != null) { |
| IResource pubspec = appFolder.findMember(DartCore.PUBSPEC_FILE_NAME); |
| |
| if (pubspec != null) { |
| String contents = FileUtilities.getContents(pubspec.getLocation().toFile(), "UTF-8"); |
| |
| if (contents != null) { |
| String name = PubYamlUtils.getPubspecName(contents); |
| |
| if (name != null) { |
| return name; |
| } |
| } |
| } |
| } |
| } catch (Exception e) { |
| |
| } |
| |
| return packageName; |
| } |
| |
| /** |
| * Returns the path string for the default dart directory - user.home/dart |
| * |
| * @return the name of the user.home/dart directory |
| */ |
| public static String getUserDefaultDartFolder() { |
| String defaultLocation = System.getProperty("user.home"); //$NON-NLS-1$ |
| return defaultLocation + File.separator + "dart" + File.separator; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns the current value of the string-valued user-defined property with the given name. |
| * Returns <code>null</code> if there is no user-defined property with the given name. |
| * <p> |
| * User-defined properties are defined in the <code>editor.properties</code> file located in the |
| * eclipse installation directory. |
| * |
| * @see DartCore#getEclipseInstallationDirectory() |
| * @param name the name of the property |
| * @return the string-valued property |
| */ |
| public static String getUserDefinedProperty(String key) { |
| |
| Properties properties = new Properties(); |
| |
| File installDirectory = getEclipseInstallationDirectory(); |
| File file = new File(installDirectory, EDITOR_PROPERTIES); |
| |
| if (file.exists()) { |
| try { |
| properties.load(new FileReader(file)); |
| } catch (FileNotFoundException e) { |
| logError(e); |
| } catch (IOException e) { |
| logError(e); |
| } |
| } |
| |
| return properties.getProperty(key); |
| } |
| |
| /** |
| * @return the version text for this plugin (i.e. 1.1.0) |
| */ |
| public static String getVersion() { |
| Version version = getPlugin().getBundle().getVersion(); |
| |
| return version.getMajor() + "." + version.getMinor() + "." + version.getMicro(); |
| } |
| |
| public static boolean is32Bit() { |
| return Platform.getOSArch().indexOf("64") == -1; |
| } |
| |
| /** |
| * Return <code>true</code> if the given resource should be analyzed. All resources are to be |
| * analyzed unless they have been excluded. |
| * |
| * @param resource the resource being tested |
| * @return <code>true</code> if the given resource should be analyzed |
| */ |
| public static boolean isAnalyzed(IResource resource) { |
| return getIgnoreManager().isAnalyzed(resource); |
| } |
| |
| /** |
| * Return true if directory contains a "packages" directory and a "pubspec.yaml" file |
| */ |
| public static boolean isApplicationDirectory(File directory) { |
| return containsPubspecFile(directory); |
| } |
| |
| /** |
| * Return true if directory contains a "packages" directory and a "pubspec.yaml" file |
| */ |
| public static boolean isApplicationDirectory(IContainer container) { |
| if (container.getLocation() == null) { |
| return false; |
| } |
| |
| File directory = container.getLocation().toFile(); |
| |
| return isApplicationDirectory(directory); |
| } |
| |
| /** |
| * Answer {@code true} if the specified resource is a build.dart file and exists either in a |
| * project or in a folder containing a pubspec file. |
| * |
| * @param file the file |
| * @return {@code true} if the file is a build.dart file that will be run by the builder |
| */ |
| public static boolean isBuildDart(IFile file) { |
| if (file == null || !file.getName().equals(BUILD_DART_FILE_NAME) || !file.exists()) { |
| return false; |
| } |
| |
| IContainer container = file.getParent(); |
| |
| // Always run build.dart in a project's root. |
| if (container.getType() == IResource.PROJECT) { |
| return true; |
| } |
| |
| return container.getFile(new Path(PUBSPEC_FILE_NAME)).exists(); |
| } |
| |
| /** |
| * Return true if directory is one that is generated by pub build |
| * |
| * @param folder the folder to be checked |
| * @return <code>true</code> if folder name matches and is sibling of pubspec.yaml |
| */ |
| public static boolean isBuildDirectory(IFolder folder) { |
| IPath location = folder.getLocation(); |
| if (location != null && folder.getName().equals(BUILD_DIRECTORY_NAME)) { |
| if (folder.getParent().findMember(PUBSPEC_FILE_NAME) != null) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Return <code>true</code> if the given file is contained in the packages directory created by |
| * pub |
| * |
| * @param file the file that is to be checked |
| * @return <code>true</code> if the given file is in packages |
| */ |
| public static boolean isContainedInPackages(File file) { |
| if (file.getAbsolutePath().contains(PACKAGES_DIRECTORY_NAME)) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Return <code>true</code> if the given file is contained in the packages directory created by |
| * pub |
| * |
| * @param file the file that is to be checked |
| * @return <code>true</code> if the given file is in packages |
| */ |
| public static boolean isContainedInPackages(IFile file) { |
| return file.getFullPath().toString().contains(DartCore.PACKAGES_DIRECTORY_PATH); |
| } |
| |
| /** |
| * Return <code>true</code> if the given file name's extension is an CSS-like extension. |
| * |
| * @param fileName the file name being tested |
| * @return <code>true</code> if the given file name's extension is an CSS-like extension |
| */ |
| public static boolean isCssLikeFileName(String fileName) { |
| return isLikeFileName(fileName, CSS_FILE_EXTENSIONS); |
| } |
| |
| /** |
| * Return <code>true</code> if the given file name's extension is a generated Dart like extension. |
| * |
| * @return <code>true</code> if the given file name's extension is a generated Dart like extension |
| */ |
| public static boolean isDartGeneratedFile(String fileName) { |
| return isLikeFileName(fileName, DART_GENERATED_FILE_EXTENSIONS); |
| } |
| |
| /** |
| * Return <code>true</code> if the name of the given {@link IFile} has a Dart-like extension. |
| * |
| * @param fileName the file name being tested |
| * @return <code>true</code> if the name of the given {@link IFile} has a Dart-like extension |
| */ |
| public static boolean isDartLikeFile(IFile file) { |
| String fileName = file.getName(); |
| return isDartLikeFileName(fileName); |
| } |
| |
| /** |
| * Return <code>true</code> if the given file name's extension is a Dart-like extension. |
| * |
| * @param fileName the file name being tested |
| * @return <code>true</code> if the given file name's extension is a Dart-like extension |
| */ |
| public static boolean isDartLikeFileName(String fileName) { |
| return StringUtilities.endsWithIgnoreCase(fileName, ".dart"); |
| } |
| |
| /** |
| * Return <code>true</code> if file is in the dart sdk lib directory |
| * |
| * @param file |
| * @return <code>true</code> if file is in dart-sdk/lib |
| */ |
| public static boolean isDartSdkLibraryFile(File file) { |
| File sdkLibrary = DartSdkManager.getManager().getSdk().getLibraryDirectory(); |
| File parentFile = file.getParentFile(); |
| while (parentFile != null) { |
| if (parentFile.equals(sdkLibrary)) { |
| return true; |
| } |
| parentFile = parentFile.getParentFile(); |
| } |
| return false; |
| } |
| |
| /** |
| * Return <code>true</code> if the given file name's extension is an HTML-like extension. |
| * |
| * @param fileName the file name being tested |
| * @return <code>true</code> if the given file name's extension is an HTML-like extension |
| */ |
| public static boolean isHtmlLikeFileName(String fileName) { |
| return isLikeFileName(fileName, HTML_FILE_EXTENSIONS); |
| } |
| |
| /** |
| * Return <code>true</code> if the given file name's extension is an image-like extension. |
| * |
| * @param fileName the file name being tested |
| * @return <code>true</code> if the given file name's extension is an image-like extension |
| */ |
| public static boolean isImageLikeFileName(String fileName) { |
| return isLikeFileName(fileName, IMAGE_FILE_EXTENSIONS); |
| } |
| |
| /** |
| * Return true if directory is build directory created by pub |
| * |
| * @param folder the folder to be checked |
| * @return <code>true</code> if folder/parent name matches and is sibling of pubspec.yaml |
| */ |
| public static boolean isInBuildDirectory(IContainer folder) { |
| while (folder.getParent() != null) { |
| if (folder.getName().equals(BUILD_DIRECTORY_NAME) |
| && folder.getParent().getFile(new Path(PUBSPEC_FILE_NAME)).exists()) { |
| return true; |
| } |
| folder = folder.getParent(); |
| } |
| return false; |
| } |
| |
| /** |
| * Return true if is in build directory created by pub |
| */ |
| public static boolean isInBuildDirectory(IResource resource) { |
| if (resource == null) { |
| return false; |
| } |
| if (!(resource instanceof IContainer)) { |
| resource = resource.getParent(); |
| } |
| return !(resource instanceof IProject || resource instanceof IWorkspaceRoot) |
| && (isBuildDirectory((IFolder) resource) || isInBuildDirectory((IContainer) resource)); |
| |
| } |
| |
| /** |
| * @return {@code true} if the given resource is located in the top-level "packages" folder of its |
| * enclosing package. |
| */ |
| public static boolean isInDuplicatePackageFolder(IResource resource) { |
| if (resource == null) { |
| return false; |
| } |
| // prepare "pub" folder |
| PubFolder pubFolder = DartCore.getProjectManager().getPubFolder(resource); |
| if (pubFolder == null) { |
| return false; |
| } |
| IPath pubPath = pubFolder.getResource().getFullPath(); |
| // check if resource is in "packages" |
| IPath resourcePath = resource.getFullPath(); |
| String[] segments = resourcePath.segments(); |
| for (int i = 1; i < segments.length - 1; i++) { |
| String segment = segments[i]; |
| if (segment.equals(PACKAGES_DIRECTORY_NAME)) { |
| return !resourcePath.uptoSegment(i).equals(pubPath); |
| } |
| } |
| // not in "packages" |
| return false; |
| } |
| |
| /** |
| * @return {@code true} if the given resource is located in the "packages" sub-folder that |
| * corresponds to the enclosing package. |
| */ |
| public static boolean isInSelfLinkedPackageFolder(IResource resource) { |
| if (resource == null) { |
| return false; |
| } |
| try { |
| // prepare "pub" folder |
| PubFolder pubFolder = DartCore.getProjectManager().getPubFolder(resource); |
| if (pubFolder == null) { |
| return false; |
| } |
| // the name of the enclosing package |
| String packageName = pubFolder.getPubspec().getName(); |
| // check if resource is in "packages" and references the enclosing package |
| String[] segments = resource.getFullPath().segments(); |
| for (int i = 0; i < segments.length - 1; i++) { |
| String segment = segments[i]; |
| if (segment.equals(PACKAGES_DIRECTORY_NAME) && segments[i + 1].equals(packageName)) { |
| return true; |
| } |
| } |
| } catch (Throwable e) { |
| // pubFolder.getPubspec() may fail |
| return false; |
| } |
| // not a self-reference |
| return false; |
| } |
| |
| /** |
| * Return <code>true</code> if the given file name's extension is an HTML-like extension. |
| * |
| * @param fileName the file name being tested |
| * @return <code>true</code> if the given file name's extension is an HTML-like extension |
| */ |
| public static boolean isJSLikeFileName(String fileName) { |
| return isLikeFileName(fileName, JS_FILE_EXTENSIONS); |
| } |
| |
| public static boolean isLinux() { |
| return !isMac() && !isWindows(); |
| } |
| |
| public static boolean isMac() { |
| // Look for the "Mac" OS name. |
| return System.getProperty("os.name").toLowerCase().startsWith("mac"); |
| } |
| |
| /** |
| * Return true if directory is one that is installed by pub |
| * |
| * @param file the file to be checked |
| * @return <code>true</code> if file name matches and is sibling of pubspec.yaml |
| */ |
| public static boolean isPackagesDirectory(File file) { |
| if (file.getName().equals(PACKAGES_DIRECTORY_NAME)) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Return true if directory is one that is installed by pub |
| * |
| * @param folder the folder to be checked |
| * @return <code>true</code> if folder name matches and is sibling of pubspec.yaml |
| */ |
| public static boolean isPackagesDirectory(IFolder folder) { |
| IPath location = folder.getLocation(); |
| return location != null && isPackagesDirectory(location.toFile()); |
| } |
| |
| /** |
| * Answer <code>true</code> if the string is a package spec |
| */ |
| public static boolean isPackageSpec(String spec) { |
| return spec != null && spec.startsWith(PACKAGE_SCHEME_SPEC); |
| } |
| |
| /** |
| * @return <code>true</code> if given {@link IResource} was installed by pub. |
| */ |
| public static boolean isPackagesResource(IResource resource) { |
| if (resource instanceof IFolder) { |
| if (isPackagesDirectory((IFolder) resource)) { |
| return true; |
| } |
| } |
| if (resource != null && resource.getParent() instanceof IFolder) { |
| IFolder parentFolder = (IFolder) resource.getParent(); |
| return isPackagesResource(parentFolder); |
| } |
| return false; |
| } |
| |
| /** |
| * Check if this URI denotes a patch file. |
| */ |
| public static boolean isPatchfile(File file) { |
| return file != null && file.getName().endsWith("_patch.dart"); |
| } |
| |
| /** |
| * @return whether we're running in the context of the eclipse plugins build |
| */ |
| public static boolean isPluginsBuild() { |
| return Platform.getBundle("com.google.dart.eclipse.core") != null; |
| } |
| |
| /** |
| * Checks if the given linkedResource points to a file in the container. This is used to check for |
| * the self link in the packages directory |
| * |
| * @param resource |
| * @param linkedResource |
| * @return <code>true</code> if the linked resource points to a file/folder in the project |
| */ |
| public static boolean isSelfLinkedResource(IContainer resource, IResource linkedResource) { |
| |
| try { |
| // if (linkedResource.getParent().getParent() == resource) { |
| String resourcePath = resource.getLocation().toFile().getCanonicalPath(); |
| String linkPath = linkedResource.getLocation().toFile().getCanonicalPath(); |
| if (linkPath.startsWith(resourcePath)) { |
| return true; |
| } |
| // } |
| } catch (IOException e) { |
| return false; |
| } |
| return false; |
| } |
| |
| /** |
| * Return <code>true</code> if the given file name's extension is an HTML-like extension. |
| * |
| * @param fileName the file name being tested |
| * @return <code>true</code> if the given file name's extension is an HTML-like extension |
| */ |
| public static boolean isTxtLikeFileName(String fileName) { |
| return isLikeFileName(fileName, TXT_FILE_EXTENSIONS); |
| } |
| |
| public static boolean isWindows() { |
| // Look for the "Windows" OS name. |
| return System.getProperty("os.name").toLowerCase().startsWith("win"); |
| } |
| |
| public static boolean isWindowsXp() { |
| // Look for the "Windows XP" OS name. |
| return System.getProperty("os.name").toLowerCase().equals("windows xp"); |
| } |
| |
| /** |
| * Log the given message as an error. |
| * |
| * @param message an explanation of why the error occurred or what it means |
| */ |
| public static void logError(String message) { |
| logErrorImpl(message, null); |
| instrumentationLogErrorImpl(message, null); |
| } |
| |
| /** |
| * Log the given exception as one representing an error. |
| * |
| * @param message an explanation of why the error occurred or what it means |
| * @param exception the exception being logged |
| */ |
| public static void logError(String message, Throwable exception) { |
| logErrorImpl(message, exception); |
| instrumentationLogErrorImpl(message, exception); |
| } |
| |
| /** |
| * Log the given exception as one representing an error. |
| * |
| * @param exception the exception being logged |
| */ |
| public static void logError(Throwable exception) { |
| logErrorImpl(exception.getMessage(), exception); |
| instrumentationLogErrorImpl(null, exception); |
| } |
| |
| /** |
| * Log the given informational message. |
| * |
| * @param message an explanation of why the error occurred or what it means |
| * @param exception the exception being logged |
| */ |
| public static void logInformation(String message) { |
| logInformation(message, null); |
| } |
| |
| /** |
| * Log the given exception as one representing an informational message. |
| * |
| * @param message an explanation of why the error occurred or what it means |
| * @param exception the exception being logged |
| */ |
| public static void logInformation(String message, Throwable exception) { |
| |
| if (DartCoreDebug.VERBOSE) { |
| ILog pluginLog = getPluginLog(); |
| if (pluginLog != null) { |
| pluginLog.log(new Status(Status.INFO, PLUGIN_ID, "INFO: " + message, exception)); |
| } |
| } |
| |
| instrumentationLogInfoImpl(message, exception); |
| } |
| |
| /** |
| * Log the given {@link RequestError}. |
| */ |
| public static void logRequestError(RequestError requestError) { |
| StringBuilder buf = new StringBuilder(); |
| buf.append("RequestError: "); |
| buf.append(requestError.getCode()); |
| buf.append("\n"); |
| buf.append(requestError.getMessage()); |
| buf.append("\n"); |
| buf.append(requestError.getStackTrace()); |
| buf.append("\n"); |
| String str = buf.toString(); |
| DartCore.logError(str); |
| } |
| |
| /** |
| * This method exists as a convenient marker for methods that have not yet been fully implemented. |
| * It should be deleted before this product ships. |
| */ |
| public static void notYetImplemented() { |
| } |
| |
| /** |
| * Removes the file extension from the given file name, if it has a Dart-like file extension. |
| * Otherwise the file name itself is returned. Note this removes the dot ('.') before the |
| * extension as well. |
| * |
| * @param fileName the name of a file |
| * @return the fileName without the Dart-like extension |
| */ |
| public static String removeDartLikeExtension(String fileName) { |
| return Util.getNameWithoutDartLikeExtension(fileName); |
| } |
| |
| /** |
| * Remove the given resource (as a path) from the set of ignored resources. |
| * |
| * @param resource the resource path to (un)ignore |
| * @throws IOException if there was an error accessing the ignore file |
| */ |
| public static void removeFromIgnores(IPath resource) throws IOException { |
| getIgnoreManager().removeFromIgnores(resource); |
| } |
| |
| /** |
| * Remove the given resource from the set of ignored resources. |
| * |
| * @param resource the resource to (un)ignore |
| * @throws IOException if there was an error accessing the ignore file |
| */ |
| public static void removeFromIgnores(IResource resource) throws IOException { |
| getIgnoreManager().removeFromIgnores(resource); |
| } |
| |
| /** |
| * Remove the given listener for dart ignore changes from the Dart Model. Has no effect if an |
| * identical listener is not registered. |
| * |
| * @param listener the non-<code>null</code> listener to remove |
| */ |
| public static void removeIgnoreListener(DartIgnoreListener listener) { |
| getIgnoreManager().removeListener(listener); |
| } |
| |
| public static void setOptions(HashMap<String, String> newOptions) { |
| |
| } |
| |
| /** |
| * Sets the current table of options. All and only the options explicitly included in the given |
| * table are remembered; all previous option settings are forgotten, including ones not explicitly |
| * mentioned. |
| * <p> |
| * Helper constants have been defined on DartPreferenceConstants for each of the option IDs |
| * (categorized in Code assist option ID, Compiler option ID and Core option ID) and some of their |
| * acceptable values (categorized in Option value). Some options accept open value sets beyond the |
| * documented constant values. |
| * <p> |
| * Note: each release may add new options. |
| * |
| * @param newOptions the new options, or <code>null</code> to reset all options to their default |
| * values |
| */ |
| public static void setOptions(Hashtable<String, String> newOptions) { |
| |
| } |
| |
| /** |
| * TESTING ONLY: Set the log used by {@link #logError(String)} and other local methods for logging |
| * errors, warnings, and information. |
| * |
| * @param log the log or <code>null</code> to use the default system log |
| * @return the log prior to calling this method or <code>null</code> for the default system log |
| */ |
| public static ILog setPluginLog(ILog log) { |
| ILog oldLog = PLUGIN_LOG; |
| PLUGIN_LOG = log; |
| return oldLog; |
| } |
| |
| /** |
| * Set a symbolic resource mapping from one resource to another. For some uses of the original |
| * resource, like serving web content, the mapped resource should be substituted. |
| * |
| * @param originalResource |
| * @param newResource |
| */ |
| public static void setResourceRemapping(IFile originalResource, IFile newResource) { |
| try { |
| String resourcePath = (newResource == null ? null |
| : newResource.getFullPath().toPortableString()); |
| originalResource.setPersistentProperty(RESOURCE_REMAP_NAME, resourcePath); |
| } catch (CoreException e) { |
| DartCore.logError(e); |
| } |
| } |
| |
| /** |
| * Sets the value of the string-valued user-defined property for the given key. |
| * <p> |
| * User-defined properties are defined in the <code>editor.properties</code> file located in the |
| * eclipse installation directory. |
| * |
| * @see DartCore#getEclipseInstallationDirectory() |
| * @param key the name of the property |
| * @param value the string-valued property |
| */ |
| public static void setUserDefinedProperty(String key, String value) { |
| |
| Properties properties = new Properties(); |
| |
| File installDirectory = getEclipseInstallationDirectory(); |
| File file = new File(installDirectory, EDITOR_PROPERTIES); |
| |
| try { |
| if (!file.exists()) { |
| file.createNewFile(); |
| } |
| properties.load(new FileReader(file)); |
| properties.setProperty(key, value); |
| properties.store(new FileWriter(file), null); |
| } catch (FileNotFoundException e) { |
| logError(e); |
| } catch (IOException e) { |
| logError(e); |
| } |
| |
| } |
| |
| /** |
| * Answer the log used by {@link #logError(String)} and other local methods for logging errors, |
| * warnings, and information. |
| * |
| * @return the {@link ILog} or {@code null} if not accessible (for example during platform |
| * shutdown) |
| */ |
| private static ILog getPluginLog() { |
| try { |
| return PLUGIN_LOG != null ? PLUGIN_LOG : getPlugin().getLog(); |
| } catch (Throwable e) { |
| return null; |
| } |
| } |
| |
| /** |
| * Record an error |
| */ |
| private static void instrumentationLogErrorImpl(String message, Throwable exception) { |
| instrumentationLogImpl(message, exception, "LogError"); |
| } |
| |
| /** |
| * Internal instrumentation message delivery implementation |
| * |
| * @param message optional message to be delivered |
| * @param exception optional exception to be delivered |
| * @param messageType message type, common values LogError/LogMessage |
| */ |
| private static void instrumentationLogImpl(String message, Throwable exception, String messageType) { |
| if (instrumentationLogErrorEnabled) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder("DartCore." + messageType); |
| try { |
| instrumentation.data("Log_Message", message != null ? message : "null"); |
| instrumentation.data("Log_Exception", exception != null ? exception.toString() : "null"); |
| if (exception != null) { |
| instrumentation.record(exception); |
| } |
| } catch (Exception e) { |
| instrumentationLogErrorEnabled = false; |
| logErrorImpl("Instrumentation failed to log error", exception); |
| } finally { |
| instrumentation.log(); |
| } |
| |
| } |
| |
| } |
| |
| /** |
| * Record an 'informational exception' |
| */ |
| private static void instrumentationLogInfoImpl(String message, Throwable exception) { |
| |
| instrumentationLogImpl(message, exception, "LogInfo"); |
| |
| } |
| |
| /** |
| * Return <code>true</code> if the given file name's extension matches one of the passed |
| * extensions. |
| * |
| * @param fileName the file name being tested |
| * @param extensions an array of file extensions to test against |
| * @return <code>true</code> if the given file name's extension matches one of the passed |
| * extensions |
| */ |
| private static boolean isLikeFileName(String fileName, String[] extensions) { |
| if (fileName == null || fileName.length() == 0) { |
| return false; |
| } |
| for (String extension : extensions) { |
| if (StringUtilities.endsWithIgnoreCase(fileName, '.' + extension)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private static void logErrorImpl(String message, Throwable exception) { |
| ILog pluginLog = getPluginLog(); |
| if (pluginLog != null) { |
| pluginLog.log(new Status(Status.ERROR, PLUGIN_ID, message, exception)); |
| } |
| } |
| |
| private IEclipsePreferences prefs; |
| |
| /** |
| * Property key for user-specified analysis server arguments. |
| */ |
| public static final String ANALYSIS_SERVER_ARG_PROP_KEY = "com.dart.tools.server.args"; |
| |
| /** |
| * Initialize a newly created instance of this class. |
| */ |
| public DartCore() { |
| PLUG_IN = this; |
| } |
| |
| /** |
| * Use dart2js if the SDK is present. |
| */ |
| public boolean getCompileWithDart2JS() { |
| return DartSdkManager.getManager().hasSdk(); |
| } |
| |
| public String getDart2jsFlags() { |
| return getPrefs().get(PREFS_DART2JS_FLAGS, ""); |
| } |
| |
| public String[] getDart2jsFlagsAsArray() { |
| return StringUtilities.parseArgumentString(getDart2jsFlags()); |
| } |
| |
| public String getDartiumLocationPref() { |
| return getPrefs().get(PREFS_DARTIUM_LOCATION, ""); |
| } |
| |
| public boolean getDisableDartBasedBuilder(IProject project) { |
| return getProjectPreferences(project).getBoolean(PROJECT_PREF_DISABLE_DART_BASED_BUILDER, false); |
| } |
| |
| public boolean getEnableAnalytics() { |
| if (DartCoreDebug.ASK_FOR_USER_ANALYTICS) { |
| return getPrefs().getBoolean(PREFS_ENABLE_ANALYTICS, false); |
| } |
| return false; |
| } |
| |
| /** |
| * Given an File, return the appropriate java.io.File representing a package root. This can be |
| * null if a package root should not be used. |
| * |
| * @param file the File |
| * @return the File for the package root, or null if none |
| */ |
| public File getPackageRoot(File file) { |
| IResource resource = ResourceUtil.getResource(file); |
| if (resource != null) { |
| return getPackageRoot(resource.getProject()); |
| } |
| return null; |
| } |
| |
| /** |
| * Given an IProject, return the appropriate java.io.File representing a package root. This can be |
| * null if a package root should not be used. |
| * |
| * @param project the IProject |
| * @return the File for the package root, or null if none |
| */ |
| public File getPackageRoot(IProject project) { |
| if (project != null) { |
| String setting = getProjectPreferences(project).get(PROJECT_PREF_PACKAGE_ROOT, ""); |
| |
| if (setting != null && setting.length() > 0) { |
| String[] paths = setting.split(File.pathSeparator); |
| return new File(paths[0]); |
| } |
| } |
| |
| File[] roots = CmdLineOptions.getOptions().getPackageRoots(); |
| |
| if (roots.length > 0) { |
| return roots[0]; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Get the core plugin preferences. Use savePrefs() to save the preferences. |
| */ |
| public IEclipsePreferences getPrefs() { |
| if (prefs == null) { |
| prefs = InstanceScope.INSTANCE.getNode(PLUGIN_ID); |
| } |
| |
| return prefs; |
| } |
| |
| public IEclipsePreferences getProjectPreferences(IProject project) { |
| ProjectScope projectScope = new ProjectScope(project); |
| |
| return projectScope.getNode(PLUGIN_ID); |
| } |
| |
| public String getSdkLocationPref() { |
| return getPrefs().get(PREFS_SDK_LOCATION, ""); |
| } |
| |
| public boolean getShowAnalyticsDailog() { |
| return getPrefs().getBoolean(PREFS_SHOW_ANALYTICS_DIALOG, true); |
| } |
| |
| /** |
| * Given an IProject, return string representing a package root to be used for all VM launches. |
| * This can be null if a package root should not be used. |
| * |
| * @param project the IProject |
| * @return the String for the package root, or null if none |
| */ |
| public String getVmPackageRoot(IProject project) { |
| if (project != null) { |
| String setting = getProjectPreferences(project).get(PROJECT_PREF_VM_PACKAGE_ROOT, ""); |
| if (!setting.isEmpty()) { |
| return setting; |
| } |
| } |
| return null; |
| } |
| |
| public boolean isAutoRunPubEnabled() { |
| return DartCore.getPlugin().getPrefs().getBoolean(PUB_AUTO_RUN_PREFERENCE, true); |
| } |
| |
| public boolean isHintsDart2JSEnabled() { |
| return DartCore.getPlugin().getPrefs().getBoolean(ENABLE_HINTS_DART2JS_PREFERENCE, true); |
| } |
| |
| public boolean isHintsEnabled() { |
| return DartCore.getPlugin().getPrefs().getBoolean(ENABLE_HINTS_PREFERENCE, true); |
| } |
| |
| public boolean isLintsEnabled() { |
| return DartCore.getPlugin().getPrefs().getBoolean(ENABLE_LINTS_PREFERENCE, false); |
| } |
| |
| /** |
| * Save the core plugin preferences |
| * |
| * @throws CoreException |
| */ |
| public void savePrefs() throws CoreException { |
| try { |
| getPrefs().flush(); |
| } catch (BackingStoreException e) { |
| throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, e.toString(), e)); |
| } |
| } |
| |
| @Override |
| public void sdkUpdated(DirectoryBasedDartSdk sdk) { |
| Job job = new CleanLibrariesJob(); |
| |
| job.schedule(); |
| } |
| |
| public void setDart2JsPreferences(String args) { |
| IEclipsePreferences prefs = getPrefs(); |
| prefs.put(PREFS_DART2JS_FLAGS, args); |
| |
| try { |
| getPrefs().flush(); |
| } catch (BackingStoreException exception) { |
| logError(exception); |
| } |
| } |
| |
| public void setDisableDartBasedBuilder(IProject project, boolean value) throws CoreException { |
| try { |
| IEclipsePreferences prefs = getProjectPreferences(project); |
| prefs.putBoolean(PROJECT_PREF_DISABLE_DART_BASED_BUILDER, value); |
| prefs.flush(); |
| } catch (BackingStoreException ex) { |
| throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, ex.toString(), ex)); |
| } |
| } |
| |
| public void setEnableAnalytics(boolean value) { |
| if (DartCoreDebug.ASK_FOR_USER_ANALYTICS) { |
| IEclipsePreferences prefs = getPrefs(); |
| prefs.putBoolean(PREFS_ENABLE_ANALYTICS, value); |
| |
| try { |
| getPrefs().flush(); |
| } catch (BackingStoreException exception) { |
| logError(exception); |
| } |
| } |
| } |
| |
| public void setPackageRoot(IProject project, String packageRootPath) throws CoreException { |
| try { |
| IEclipsePreferences prefs = getProjectPreferences(project); |
| prefs.put(PROJECT_PREF_PACKAGE_ROOT, packageRootPath); |
| prefs.flush(); |
| } catch (BackingStoreException ex) { |
| throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, ex.toString(), ex)); |
| } |
| } |
| |
| public void setShowAnalyticsDialogFalse() { |
| IEclipsePreferences prefs = getPrefs(); |
| prefs.putBoolean(PREFS_SHOW_ANALYTICS_DIALOG, false); |
| |
| try { |
| getPrefs().flush(); |
| } catch (BackingStoreException exception) { |
| logError(exception); |
| } |
| } |
| |
| public void setVmPackageRoot(IProject project, String packageRootPath) throws CoreException { |
| try { |
| IEclipsePreferences prefs = getProjectPreferences(project); |
| prefs.put(PROJECT_PREF_VM_PACKAGE_ROOT, packageRootPath); |
| prefs.flush(); |
| } catch (BackingStoreException ex) { |
| throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, ex.toString(), ex)); |
| } |
| } |
| |
| @Override |
| public void start(BundleContext context) throws Exception { |
| super.start(context); |
| |
| CmdLineOptions.setOptions(CmdLineOptions.parseCmdLine(Platform.getApplicationArgs())); |
| CmdLineOptions.getOptions().printWarnings(); |
| |
| if (DartCoreDebug.PERF_THREAD_CONTENTION_MONIOR) { |
| try { |
| java.lang.management.ThreadMXBean th = ManagementFactory.getThreadMXBean(); |
| th.setThreadContentionMonitoringEnabled(true); |
| } catch (UnsupportedOperationException e) { |
| } |
| } |
| |
| AnalysisEngine analysisEngine = AnalysisEngine.getInstance(); |
| analysisEngine.setLogger(new Logger() { |
| @Override |
| public void logError(String message) { |
| DartCore.logError(message); |
| } |
| |
| @Override |
| public void logError(String message, Throwable exception) { |
| DartCore.logError(message, exception); |
| } |
| |
| @Override |
| public void logInformation(String message) { |
| DartCore.logInformation(message); |
| } |
| |
| @Override |
| public void logInformation(String message, Throwable exception) { |
| DartCore.logInformation(message, exception); |
| } |
| }); |
| Logging.setLogger(new com.google.dart.server.utilities.logging.Logger() { |
| @Override |
| public void logError(String message) { |
| DartCore.logError(message); |
| } |
| |
| @Override |
| public void logError(String message, Throwable exception) { |
| DartCore.logError(message, exception); |
| } |
| |
| @Override |
| public void logInformation(String message) { |
| DartCore.logInformation(message); |
| } |
| |
| @Override |
| public void logInformation(String message, Throwable exception) { |
| DartCore.logInformation(message, exception); |
| } |
| }); |
| |
| DartSdkManager.getManager().addSdkListener(this); |
| if (!DartCoreDebug.ENABLE_ANALYSIS_SERVER) { |
| getProjectManager().hookListeners(); |
| } else { |
| getAnalysisServer(); |
| } |
| } |
| |
| @Override |
| public void stop(BundleContext context) throws Exception { |
| DartSdkManager.getManager().removeSdkListener(this); |
| |
| try { |
| if (!DartCoreDebug.ENABLE_ANALYSIS_SERVER) { |
| getProjectManager().stop(); |
| } |
| |
| synchronized (analysisServerLock) { |
| if (analysisServer != null) { |
| analysisServer.server_shutdown(); |
| } |
| } |
| |
| if (DartCoreDebug.METRICS) { |
| StringWriter writer = new StringWriter(); |
| PerformanceManager.getInstance().printMetrics(new PrintWriter(writer)); |
| String metricsInfo = writer.toString(); |
| if (metricsInfo.length() > 0) { |
| getLog().log(new Status(Status.INFO, PLUGIN_ID, metricsInfo, null)); |
| } |
| } |
| } finally { |
| super.stop(context); |
| } |
| } |
| } |